/*
 * Copyright 2015 泛泛o0之辈
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.jfast.framework.jdbc.orm;

import cn.jfast.framework.base.util.StringUtils;
import java.sql.SQLException;

/**
 * 解析预编译格式SQL
 */
public abstract class Parser extends  Wrapper{

    /**
     * 获得 预编译SQl格式
     * @return
     * @throws SQLException
     */
    public String parseSql( ) throws SQLException, SqlException {
        String sql = formatFirst(getSql());
        String[] sqlParams = StringUtils.substringsBetween(sql, ":", " ");
        if(null != sqlParams && sqlParams.length>0){
        	for(String sqlParam:sqlParams){
                Object value = paramMaps.get(sqlParam.toLowerCase());
                if(null == value) {
                    sqlFields.add(null);
                    sql = sql.replaceAll(":" + sqlParam, "?");
                } else {
                    if (value.getClass().isArray()) {
                        StringBuffer inSql = new StringBuffer("(");
                        for (Object obj : (Object[]) value) {
                            inSql.append("?,");
                            sqlFields.add(obj);
                        }
                        inSql.deleteCharAt(inSql.lastIndexOf(",")).append(")");
                        sql = sql.replaceAll("=\\s*:" + sqlParam, " IN :" + sqlParam)
                                .replaceAll(":" + sqlParam, inSql.toString());
                    } else {
                        sqlFields.add(value);
                        sql = sql.replaceAll(":" + sqlParam, "?");
                    }
                }
            }
        }
        String[] sqlCdataParams = StringUtils.substringsBetween(sql, "[CDATA[", "]]");
        if(null != sqlCdataParams && sqlCdataParams.length>0){
        	for(String sqlParam:sqlCdataParams){
                Object value = paramMaps.get(sqlParam.toLowerCase());
                if(null == value) {
                	sqlFields.add(StringUtils.countAppearNums(sql.substring(0,sql.indexOf("[CDATA["+sqlParam+"]]")),"?"),null);
                    sql = sql.replaceFirst("\\[CDATA\\[" + sqlParam+"\\]\\]", "?");
                } else {
                    if (value.getClass().isArray()) {
                        StringBuffer inSql = new StringBuffer();
                        int index = StringUtils.countAppearNums(sql.substring(0,sql.indexOf("[CDATA["+sqlParam+"]]")),"?");
                        for (Object obj : (Object[]) value) {
                            inSql.append("?,");
                            sqlFields.add(index++,obj);
                        }
                        inSql.deleteCharAt(inSql.lastIndexOf(","));
                        sql = sql.replaceFirst("\\[CDATA\\[" + sqlParam+"\\]\\]",inSql.toString());
                    } else {
                    	sqlFields.add(StringUtils.countAppearNums(sql.substring(0,sql.indexOf("[CDATA["+sqlParam+"]]")),"?"),value);
                        sql = sql.replaceFirst("\\[CDATA\\[" + sqlParam+"\\]\\]", "?");
                    }
                }
            }
        }
        return formatLast(sql);
    }

    private String formatFirst(String sql){
        return sql.replaceAll(","," , ")
                .replaceAll("\\("," ( ")
                .replaceAll("\\)"," ) ")+" ";
    }
    
    private String formatLast(String sql){
        return sql.replaceAll("\\s+", " ").replaceAll("\\s\\(", "(").replaceAll("\\s,", ",");
    }
    /**
     * 获得JFast 标准Sql格式
     * @return
     */
    public abstract String getSql() throws SqlException;

}
